import Router from '@koa/router';
import { Context, Next } from 'koa';
import { AuthService } from '../services/AuthService';
import { UserService } from '../services/UserService';
import { SystemService } from '../services/SystemService';
import { validateRequest, CommonRules } from '../middleware/validation';
import { authMiddleware, adminAuthMiddleware, optionalAuthMiddleware } from '../middleware/auth';
import { rateLimitMiddleware, ipRateLimit, userRateLimit } from '../middleware/rateLimit';
import { Types } from 'mongoose';
import { SystemDAO } from '../dao/SystemDAO';
import { UserDAO } from '../dao/UserDAO';
import { SessionDAO } from '../dao/SessionDAO';
import { createDevLogger } from '../middleware/logger';

const router = new Router({ prefix: '/api/auth' });
const logger = createDevLogger();

// DAO实例
const systemDAO = new SystemDAO();
const userDAO = new UserDAO();
const sessionDAO = new SessionDAO();

// 服务实例
const authService = new AuthService();
const userService = new UserService(userDAO, sessionDAO);
const systemService = new SystemService();

/**
 * 用户登录
 * POST /api/auth/login
 */
router.post('/login',
  ipRateLimit(10, 15 * 60 * 1000), // 15分钟内最多10次登录尝试
  validateRequest([
    CommonRules.username,
    CommonRules.password,
    CommonRules.systemCode,
    {
      field: 'rememberMe',
      required: false,
      type: 'boolean',
      message: 'rememberMe必须是布尔值'
    }
  ]),
  async (ctx: Context) => {
    try {
      const { username, password, systemCode, rememberMe = false } = ctx.request.body as any;

      // 验证系统
      const system = await systemDAO.findByCode(systemCode);
      if (!system) {
        ctx.status = 400;
        ctx.body = {
          success: false,
          message: '系统不存在'
        };
        return;
      }

      if (!system.canAccess()) {
        ctx.status = 403;
        ctx.body = {
          success: false,
          message: '系统暂时不可访问'
        };
        return;
      }

      const result = await authService.login(username, password, systemCode, rememberMe);
      
      if (result.success) {
        ctx.body = {
          success: true,
          message: '登录成功',
          data: {
            user: result.user,
            sessionId: result.sessionId,
            permissions: result.permissions
          }
        };
      } else {
        ctx.status = 401;
        ctx.body = {
          success: false,
          message: result.message
        };
      }
    } catch (error) {
      console.error('用户登录失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: '登录失败，请稍后重试'
      };
    }
  }
);

/**
 * 用户登出
 * POST /api/auth/logout
 */
router.post('/logout',
  optionalAuthMiddleware,
  async (ctx: Context) => {
    try {
      const sessionId = ctx.state.sessionId;
      
      if (sessionId) {
        await authService.logout(sessionId);
      }
      
      ctx.body = {
        success: true,
        message: '登出成功'
      };
    } catch (error) {
      console.error('用户登出失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: '登出失败，请稍后重试'
      };
    }
  }
);

/**
 * 检查登录状态
 * GET /api/auth/check
 */
router.get('/check',
  optionalAuthMiddleware,
  async (ctx: Context) => {
    try {
      const sessionId = ctx.state.sessionId;
      
      if (!sessionId) {
        ctx.body = {
          success: false,
          message: '未登录',
          data: { isLoggedIn: false }
        };
        return;
      }

      const result = await authService.checkLoginStatus(sessionId);
       
       ctx.body = {
         success: true,
         message: result.valid ? '已登录' : '登录状态无效',
         data: {
           isLoggedIn: result.valid,
           user: result.user,
           session: result.session
         }
       };
    } catch (error) {
      console.error('检查登录状态失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: '检查登录状态失败'
      };
    }
  }
);

/**
 * SSO登录（重定向模式）
 * POST /api/auth/sso/login
 */
router.post('/sso/login',
  ipRateLimit(20, 15 * 60 * 1000), // 15分钟内最多20次SSO登录尝试
  validateRequest([
    CommonRules.username,
    CommonRules.password,
    CommonRules.systemCode
  ]),
  async (ctx: Context) => {
    try {
      const { username, password, systemCode } = ctx.request.body as any;
      
      const result = await authService.ssoLogin(systemCode, username, password, ctx.ip, ctx.get('User-Agent'));
       
       if (result.success) {
         ctx.body = {
           success: true,
           message: 'SSO登录成功',
           data: {
             user: result.user,
             sessionId: result.sessionId,
             system: result.system
           }
         };
      } else {
        ctx.status = 401;
        ctx.body = {
          success: false,
          message: result.message
        };
      }
    } catch (error) {
      console.error('SSO登录失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: 'SSO登录失败，请稍后重试'
      };
    }
  }
);

/**
 * SSO验证接口（供子系统调用）
 * GET /api/auth/sso/verify
 */
router.get('/sso/verify',
  validateRequest([
    {
      field: 'sessionId',
      required: true,
      type: 'string',
      minLength: 10,
      message: 'sessionId不能为空且长度至少10位'
    },
    {
      field: 'systemCode',
      required: true,
      type: 'string',
      message: '系统代码不能为空'
    }
  ]),
  async (ctx: Context) => {
    try {
      const { sessionId, systemCode } = ctx.query as any;
      
      const result = await authService.verifySSOSession(sessionId, systemCode);
       
       if (result.valid) {
         ctx.body = {
           success: true,
           message: 'SSO验证成功',
           data: {
             user: result.user,
             session: result.session
           }
         };
      } else {
        ctx.status = 401;
        ctx.body = {
          success: false,
          message: result.message,
          data: {
            ssoLoginUrl: result.ssoLoginUrl
          }
        };
      }
    } catch (error) {
      console.error('SSO验证失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: 'SSO验证失败，请稍后重试'
      };
    }
  }
);

/**
 * SSO统一登出
 * POST /api/auth/sso/logout
 */
router.post('/sso/logout',
  validateRequest([
    {
      field: 'sessionId',
      required: true,
      type: 'string',
      minLength: 10,
      message: 'sessionId不能为空且长度至少10位'
    }
  ]),
  async (ctx: Context) => {
    try {
      const { sessionId } = ctx.request.body as any;
      
      await authService.ssoLogout(sessionId);
      
      ctx.body = {
        success: true,
        message: 'SSO登出成功'
      };
    } catch (error) {
      console.error('SSO登出失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: 'SSO登出失败，请稍后重试'
      };
    }
  }
);

/**
 * 跨系统会话验证
 * GET /api/auth/session/:sessionId
 */
router.get('/session/:sessionId',
  async (ctx: Context) => {
    try {
      const { sessionId } = ctx.params;
      const { systemCode } = ctx.query as any;
      
      if (!sessionId || !systemCode) {
        ctx.status = 400;
        ctx.body = {
          success: false,
          message: 'sessionId和systemCode不能为空'
        };
        return;
      }
      
      const result = await authService.verifySessionById(sessionId);
      
      if (result.valid) {
        ctx.body = {
          success: true,
          message: '会话验证成功',
          data: {
            user: result.user,
            session: result.session
          }
        };
      } else {
        ctx.status = 401;
        ctx.body = {
          success: false,
          message: result.message
        };
      }
    } catch (error) {
      console.error('会话验证失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: '会话验证失败，请稍后重试'
      };
    }
  }
);

/**
 * 会话同步接口
 * POST /api/auth/session/sync
 */
router.post('/session/sync',
  validateRequest([
    {
      field: 'sessionId',
      required: true,
      type: 'string',
      minLength: 10,
      message: 'sessionId不能为空且长度至少10位'
    },
    {
      field: 'systemCode',
      required: true,
      type: 'string',
      message: '系统代码不能为空'
    },
    {
      field: 'action',
      required: true,
      type: 'string',
      message: 'action必须是login、logout或refresh'
    }
  ]),
  async (ctx: Context) => {
    try {
      const { sessionId, systemCode } = ctx.request.body as any;
      
      const result = await authService.syncSession(sessionId, systemCode);
      
      ctx.body = {
        success: true,
        message: '会话同步成功',
        data: result
      };
    } catch (error) {
      console.error('会话同步失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: '会话同步失败，请稍后重试'
      };
    }
  }
);

/**
 * 超级管理员登录
 * POST /api/auth/super-admin/login
 */
router.post('/super-admin/login',
  ipRateLimit(5, 15 * 60 * 1000), // 15分钟内最多5次超级管理员登录尝试
  validateRequest([
    CommonRules.username,
    CommonRules.password,
    {
      field: 'verificationCode',
      required: true,
      type: 'string',
      minLength: 4,
      maxLength: 10,
      message: '验证码必须是4-10位字符'
    }
  ]),
  async (ctx: Context) => {
    try {
      const { username, password, verificationCode } = ctx.request.body as any;
      
      const result = await authService.superAdminLogin(username, password, verificationCode);
      
      if (result.success) {
        ctx.body = {
          success: true,
          message: '超级管理员登录成功',
          data: {
            sessionId: result.sessionId,
            user: result.user,
            isSuperAdmin: true
          }
        };
      } else {
        ctx.status = 401;
        ctx.body = {
          success: false,
          message: result.message
        };
      }
    } catch (error) {
      console.error('超级管理员登录失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: '超级管理员登录失败，请稍后重试'
      };
    }
  }
);

/**
 * 管理员登录
 * POST /api/auth/admin/login
 */
router.post('/admin/login',
  ipRateLimit(8, 15 * 60 * 1000), // 15分钟内最多8次管理员登录尝试
  validateRequest([
    CommonRules.username,
    CommonRules.password
  ]),
  async (ctx: Context) => {
    try {
      const { username, password } = ctx.request.body as any;
      
      const result = await authService.adminLogin(username, password, ctx.ip, ctx.get('User-Agent') || '');
      
      if (result.success) {
        ctx.body = {
          success: true,
          message: '管理员登录成功',
          data: {
            sessionId: result.sessionId,
            user: result.user,
            isSuperAdmin: false
          }
        };
      } else {
        ctx.status = 401;
        ctx.body = {
          success: false,
          message: result.message
        };
      }
    } catch (error) {
      console.error('管理员登录失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: '管理员登录失败，请稍后重试'
      };
    }
  }
);

/**
 * 检查管理员权限
 * GET /api/auth/admin/check
 */
router.get('/admin/check',
  adminAuthMiddleware,
  async (ctx: Context) => {
    try {
      const sessionId = ctx.state.sessionId;
      
      const result = await authService.checkAdminPermission(sessionId);
      
      if (result.valid) {
        ctx.body = {
          success: true,
          message: '管理员权限验证成功',
          data: {
            user: result.user,
            session: result.session,
            isSuperAdmin: result.isSuperAdmin
          }
        };
      } else {
        ctx.status = 403;
        ctx.body = {
          success: false,
          message: result.message
        };
      }
    } catch (error) {
      console.error('管理员权限验证失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: '管理员权限验证失败'
      };
    }
  }
);

/**
 * 管理员登出
 * POST /api/auth/admin/logout
 */
router.post('/admin/logout',
  adminAuthMiddleware,
  async (ctx: Context) => {
    try {
      const sessionId = ctx.state.sessionId;
      
      await authService.adminLogout(sessionId);
      
      ctx.body = {
        success: true,
        message: '管理员登出成功'
      };
    } catch (error) {
      console.error('管理员登出失败:', error);
      ctx.status = 500;
      ctx.body = {
        success: false,
        message: '管理员登出失败，请稍后重试'
      };
    }
  }
);

export default router;
